home *** CD-ROM | disk | FTP | other *** search
/ Computer Inter@ctive 16 / Computer Interactive cdrom 16 - dic 98.iso / zdnetit / content / CLASSBLD.ZIP / Include / CB_UniqueValueTree.h < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-06  |  14.7 KB  |  505 lines

  1. #ifndef CB_UNIQUEVALUETREE_H
  2. #define CB_UNIQUEVALUETREE_H
  3.  
  4. #include <assert.h>
  5.  
  6. #include "CB_IteratorMulti.h"
  7.  
  8. // defines for include files
  9. #define RELATION_UNIQUEVALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  10. private:\
  11.     ClassTo* _first##NameTo;\
  12.     int _count##NameTo;\
  13. \
  14. public:\
  15.     void Add##NameTo(ClassTo* item);\
  16.     void Remove##NameTo(ClassTo* item);\
  17.     void RemoveAll##NameTo();\
  18.     void DeleteAll##NameTo();\
  19.     void Replace##NameTo(ClassTo* item, ClassTo* newItem);\
  20.     ClassTo* GetFirst##NameTo();\
  21.     ClassTo* GetLast##NameTo();\
  22.     ClassTo* GetNext##NameTo(ClassTo* pos);\
  23.     ClassTo* GetPrev##NameTo(ClassTo* pos);\
  24.     int Get##NameTo##Count();\
  25.     ITERATOR_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo)
  26.  
  27. #define RELATION_NOFILTER_UNIQUEVALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  28. private:\
  29.     ClassTo* _first##NameTo;\
  30.     int _count##NameTo;\
  31. \
  32. public:\
  33.     void Add##NameTo(ClassTo* item);\
  34.     void Remove##NameTo(ClassTo* item);\
  35.     void RemoveAll##NameTo();\
  36.     void DeleteAll##NameTo();\
  37.     void Replace##NameTo(ClassTo* item, ClassTo* newItem);\
  38.     ClassTo* GetFirst##NameTo();\
  39.     ClassTo* GetLast##NameTo();\
  40.     ClassTo* GetNext##NameTo(ClassTo* pos);\
  41.     ClassTo* GetPrev##NameTo(ClassTo* pos);\
  42.     int Get##NameTo##Count();\
  43.     ITERATOR_NOFILTER_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo)
  44.  
  45. #define RELATION_UNIQUEVALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  46. public:\
  47.     ClassFrom* _ref##NameFrom;\
  48.     ClassTo* _parent##NameFrom;\
  49.     ClassTo* _left##NameFrom;\
  50.     ClassTo* _right##NameFrom;\
  51. \
  52. public:\
  53.     ClassFrom* Get##NameFrom() { return _ref##NameFrom; };
  54.  
  55. // defines implementation
  56. #define INIT_UNIQUEVALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  57.     _first##NameTo = (ClassTo*)0;\
  58.     _count##NameTo = 0;
  59.  
  60. #define EXIT_UNIQUEVALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  61.     { for (ClassTo* item = GetFirst##NameTo(); item; item = GetFirst##NameTo())\
  62.           Remove##NameTo(item); }
  63.  
  64. #define REPLACE_UNIQUEVALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  65.     _first##NameTo = pOld->_first##NameTo;\
  66.     _count##NameTo = pOld->_count##NameTo;\
  67.     pOld->_first##NameTo = (ClassTo*)0;\
  68.     { for (ClassTo* item = GetFirst##NameTo(); item; item = GetNext##NameTo(item))\
  69.           item->_ref##NameFrom = this; }
  70.  
  71. #define INIT_UNIQUEVALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  72.     _ref##NameFrom = (ClassFrom*)0;\
  73.     _parent##NameFrom = (ClassTo*)0;\
  74.     _left##NameFrom = (ClassTo*)0;\
  75.     _right##NameFrom = (ClassTo*)0;
  76.  
  77. #define EXIT_UNIQUEVALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  78.     if (_ref##NameFrom)\
  79.         _ref##NameFrom->Remove##NameTo(this);
  80.  
  81. #define REPLACE_UNIQUEVALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  82.     _ref##NameFrom = (ClassFrom*)0;\
  83.     _parent##NameFrom = (ClassTo*)0;\
  84.     _left##NameFrom = (ClassTo*)0;\
  85.     _right##NameFrom = (ClassTo*)0;\
  86.     if (pOld->_ref##NameFrom)\
  87.         pOld->_ref##NameFrom->Replace##NameTo(pOld, this);
  88.  
  89. #define METHODS_UNIQUEVALUETREE_ACTIVE(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  90. void ClassFrom##::Add##NameTo(ClassTo* item)\
  91. {\
  92.     METHOD_UNIQUEVALUETREE_ADD(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  93. }\
  94. \
  95. void ClassFrom##::Remove##NameTo(ClassTo* item)\
  96. {\
  97.     METHOD_UNIQUEVALUETREE_REMOVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  98. }\
  99. \
  100. void ClassFrom##::RemoveAll##NameTo()\
  101. {\
  102.     METHOD_UNIQUEVALUETREE_REMOVEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  103. }\
  104. \
  105. void ClassFrom##::DeleteAll##NameTo()\
  106. {\
  107.     METHOD_UNIQUEVALUETREE_DELETEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  108. }\
  109. \
  110. void ClassFrom##::Replace##NameTo(ClassTo* item, ClassTo* newItem)\
  111. {\
  112.     METHOD_UNIQUEVALUETREE_REPLACE(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  113. }\
  114. \
  115. ClassTo* ClassFrom##::GetFirst##NameTo()\
  116. {\
  117.     METHOD_UNIQUEVALUETREE_GETFIRST(ClassFrom, NameFrom, ClassTo, NameTo) \
  118. }\
  119. \
  120. ClassTo* ClassFrom##::GetLast##NameTo()\
  121. {\
  122.     METHOD_UNIQUEVALUETREE_GETLAST(ClassFrom, NameFrom, ClassTo, NameTo) \
  123. }\
  124. \
  125. ClassTo* ClassFrom##::GetNext##NameTo(ClassTo* pos)\
  126. {\
  127.     METHOD_UNIQUEVALUETREE_GETNEXT(ClassFrom, NameFrom, ClassTo, NameTo) \
  128. }\
  129. \
  130. ClassTo* ClassFrom##::GetPrev##NameTo(ClassTo* pos)\
  131. {\
  132.     METHOD_UNIQUEVALUETREE_GETPREV(ClassFrom, NameFrom, ClassTo, NameTo) \
  133. }\
  134. \
  135. int ClassFrom##::Get##NameTo##Count()\
  136. {\
  137.     METHOD_UNIQUEVALUETREE_GETCOUNT(ClassFrom, NameFrom, ClassTo, NameTo) \
  138. }
  139.  
  140. #define METHOD_UNIQUEVALUETREE_ADD(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  141.     assert(this);\
  142. \
  143.     assert(item);\
  144.     assert(item->_ref##NameFrom == (ClassFrom*)0);\
  145. \
  146.     _count##NameTo++;\
  147. \
  148.     item->_ref##NameFrom = this;\
  149. \
  150.     if (_first##NameTo)\
  151.     {\
  152.         ClassTo* current = _first##NameTo;\
  153.         unsigned long bit = 0x1;\
  154.         while (1)\
  155.         {\
  156.             assert(current->member != item->member);\
  157. \
  158.             if ((current->member & bit) == (item->member & bit))\
  159.             {\
  160.                 if (current->_left##NameFrom)\
  161.                 {\
  162.                     current = current->_left##NameFrom;\
  163.                 }\
  164.                 else\
  165.                 {\
  166.                     current->_left##NameFrom = item;\
  167.                     item->_parent##NameFrom = current;\
  168.                     break;\
  169.                 }\
  170.             }\
  171.             else\
  172.             {\
  173.                 if (current->_right##NameFrom)\
  174.                 {\
  175.                     current = current->_right##NameFrom;\
  176.                 }\
  177.                 else\
  178.                 {\
  179.                     current->_right##NameFrom = item;\
  180.                     item->_parent##NameFrom = current;\
  181.                     break;\
  182.                 }\
  183.             }\
  184. \
  185.             bit <<= 1;\
  186.         }\
  187.     }\
  188.     else\
  189.     {\
  190.         _first##NameTo = item;\
  191.     }
  192.  
  193. #define METHOD_UNIQUEVALUETREE_REMOVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  194.     assert(this);\
  195. \
  196.     assert(item);\
  197.     assert(item->_ref##NameFrom == this);\
  198. \
  199.     ClassFrom##::##NameTo##Iterator::Check(item);\
  200. \
  201.     _count##NameTo--;\
  202. \
  203.     ClassTo* replacement = 0;\
  204.     ClassTo* move = 0;\
  205.     if (item->_left##NameFrom)\
  206.     {\
  207.         replacement = item->_left##NameFrom;\
  208.         replacement->_parent##NameFrom = item->_parent##NameFrom;\
  209.         move = item->_right##NameFrom;\
  210.     }\
  211.     else if (item->_right##NameFrom)\
  212.     {\
  213.         replacement = item->_right##NameFrom;\
  214.         replacement->_parent##NameFrom = item->_parent##NameFrom;\
  215.     }\
  216. \
  217.     ClassTo* parent = item->_parent##NameFrom;\
  218.     if (parent)\
  219.     {\
  220.         if (parent->_left##NameFrom == item)\
  221.         {\
  222.             parent->_left##NameFrom = replacement;\
  223.         }\
  224.         else\
  225.         {\
  226.             parent->_right##NameFrom = replacement;\
  227.         }\
  228.     }\
  229.     else\
  230.     {\
  231.         _first##NameTo = replacement;\
  232.     }\
  233. \
  234.     if (replacement)\
  235.     {\
  236.         while (1)\
  237.         {\
  238.             ClassTo* tmp = replacement->_right##NameFrom;\
  239.             replacement->_right##NameFrom = move;\
  240.             if (move)\
  241.             {\
  242.                 move->_parent##NameFrom = replacement;\
  243.             }\
  244.             \
  245.             if (!replacement->_left##NameFrom)\
  246.             {\
  247.                 if (tmp)\
  248.                 {\
  249.                     replacement->_left##NameFrom = tmp;\
  250.                     tmp = 0;\
  251.                 }\
  252.                 else\
  253.                 {\
  254.                     break;\
  255.                 }\
  256.             }\
  257.             move = tmp;\
  258.             replacement = replacement->_left##NameFrom;\
  259.         }\
  260.     }\
  261. \
  262.     item->_ref##NameFrom = (ClassFrom*)0;\
  263.     item->_parent##NameFrom = (ClassTo*)0;\
  264.     item->_left##NameFrom = (ClassTo*)0;\
  265.     item->_right##NameFrom = (ClassTo*)0;
  266.  
  267. #define METHOD_UNIQUEVALUETREE_REMOVEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  268.     assert(this);\
  269. \
  270.     for (ClassTo* item = GetFirst##NameTo(); item; item = GetFirst##NameTo())\
  271.           Remove##NameTo(item);
  272.  
  273. #define METHOD_UNIQUEVALUETREE_DELETEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  274.     assert(this);\
  275. \
  276.     for (ClassTo* item = GetFirst##NameTo(); item; item = GetFirst##NameTo())\
  277.           delete item;
  278.  
  279. #define METHOD_UNIQUEVALUETREE_REPLACE(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  280.     assert(this);\
  281. \
  282.     assert(item);\
  283.     assert(item->_ref##NameFrom == this);\
  284. \
  285.     assert(newItem);\
  286.     assert(newItem->_ref##NameFrom == (ClassFrom*)0);\
  287. \
  288.     if (item->member == newItem->member)\
  289.     {\
  290.         ClassFrom##::##NameTo##Iterator::Check(item, newItem);\
  291.         if (_first##NameTo == item)\
  292.         {\
  293.             _first##NameTo = newItem;\
  294.         }\
  295.         if (item->_parent##NameFrom)\
  296.         {\
  297.             if (item->_parent##NameFrom->_left##NameFrom == item)\
  298.             {\
  299.                 item->_parent##NameFrom->_left##NameFrom = newItem;\
  300.             }\
  301.             else if (item->_parent##NameFrom->_right##NameFrom == item)\
  302.             {\
  303.                 item->_parent##NameFrom->_right##NameFrom = newItem;\
  304.             }\
  305.         }\
  306.         newItem->_ref##NameFrom = this;\
  307.         newItem->_parent##NameFrom = item->_parent##NameFrom;\
  308.         newItem->_left##NameFrom = item->_left##NameFrom;\
  309.         newItem->_right##NameFrom = item->_right##NameFrom;\
  310.         item->_ref##NameFrom = (ClassFrom*)0;\
  311.         item->_parent##NameFrom = (ClassTo*)0;\
  312.         item->_left##NameFrom = (ClassTo*)0;\
  313.         item->_right##NameFrom = (ClassTo*)0;\
  314.     }\
  315.     else\
  316.     {\
  317.         ClassFrom##::##NameTo##Iterator::Check(item);\
  318.         Remove##NameTo(item);\
  319.         Add##NameTo(newItem);\
  320.     }
  321.  
  322. #define METHOD_UNIQUEVALUETREE_GETFIRST(ClassFrom, NameFrom, ClassTo, NameTo) \
  323.     assert(this);\
  324.     return _first##NameTo;
  325.  
  326. #define METHOD_UNIQUEVALUETREE_GETLAST(ClassFrom, NameFrom, ClassTo, NameTo) \
  327.     assert(this);\
  328. \
  329.     ClassTo* result = _first##NameTo;\
  330.     while (result)\
  331.     {\
  332.         while (result->_right##NameFrom)\
  333.         {\
  334.             result = result->_right##NameFrom;\
  335.         }\
  336. \
  337.         if (result->_left##NameFrom)\
  338.         {\
  339.             result = result->_left##NameFrom;\
  340.         }\
  341.         else\
  342.         {\
  343.             break;\
  344.         }\
  345.     }\
  346. \
  347.     return result;
  348.  
  349. #define METHOD_UNIQUEVALUETREE_GETNEXT(ClassFrom, NameFrom, ClassTo, NameTo) \
  350.     assert(this);\
  351. \
  352.     ClassTo* result = 0;\
  353.     if (pos == (ClassTo*)0)\
  354.         result = _first##NameTo;\
  355.     else\
  356.     {\
  357.         assert(pos->_ref##NameFrom == this);\
  358. \
  359.         if (pos->_left##NameFrom)\
  360.         {\
  361.             result = pos->_left##NameFrom;\
  362.         }\
  363.         else\
  364.         {\
  365.             if (pos->_right##NameFrom)\
  366.             {\
  367.                 result = pos->_right##NameFrom;\
  368.             }\
  369.             else\
  370.             {\
  371.                 ClassTo* parent = pos->_parent##NameFrom;\
  372.                 while (parent && (parent->_right##NameFrom == 0 || parent->_right##NameFrom == pos))\
  373.                 {\
  374.                     pos = parent;\
  375.                     parent = parent->_parent##NameFrom;\
  376.                 }\
  377. \
  378.                 if (parent)\
  379.                 {\
  380.                     result = parent->_right##NameFrom;\
  381.                 }\
  382.             }\
  383.         }\
  384.     }\
  385. \
  386.     return result;
  387.  
  388. #define METHOD_UNIQUEVALUETREE_GETPREV(ClassFrom, NameFrom, ClassTo, NameTo) \
  389.     assert(this);\
  390. \
  391.     ClassTo* result = 0;\
  392.     if (pos == (ClassTo*)0)\
  393.         result = GetLast##NameTo();\
  394.     else\
  395.     {\
  396.         assert(pos->_ref##NameFrom == this);\
  397. \
  398.         if (pos->_parent##NameFrom)\
  399.         {\
  400.             if (pos->_parent##NameFrom->_left##NameFrom == pos || pos->_parent##NameFrom->_left##NameFrom == 0)\
  401.             {\
  402.                 result = pos->_parent##NameFrom;\
  403.             }\
  404.             else /* Right branche and valid left branche */\
  405.             {\
  406.                 result = pos->_parent##NameFrom->_left##NameFrom;\
  407.                 while (1)\
  408.                 {\
  409.                     while (result->_right##NameFrom)\
  410.                     {\
  411.                         result = result->_right##NameFrom;\
  412.                     }\
  413. \
  414.                     if (result->_left##NameFrom)\
  415.                     {\
  416.                         result = result->_left##NameFrom;\
  417.                     }\
  418.                     else\
  419.                     {\
  420.                         break;\
  421.                     }\
  422.                 }\
  423.             }\
  424.         }\
  425.     }\
  426. \
  427.     return result;
  428.  
  429. #define METHOD_UNIQUEVALUETREE_GETCOUNT(ClassFrom, NameFrom, ClassTo, NameTo) \
  430.     assert(this);\
  431.     return _count##NameTo;
  432.  
  433. #define METHODS_UNIQUEVALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo)
  434.  
  435. #ifndef _BODY_VALUETREE_FIND
  436. #define _BODY_VALUETREE_FIND(member, value, ClassFrom, NameFrom, ClassTo, NameTo) \
  437.     ClassTo* result = 0;\
  438.     if (_first##NameTo)\
  439.     {\
  440.         ClassTo* item = _first##NameTo;\
  441.         unsigned long bit = 0x1;\
  442.         while (1)\
  443.         {\
  444.             if (item->member == value)\
  445.             {\
  446.                 result = item;\
  447.                 break;\
  448.             }\
  449. \
  450.             if ((item->member & bit) == (value & bit))\
  451.             {\
  452.                 if (item->_left##NameFrom)\
  453.                 {\
  454.                     item = item->_left##NameFrom;\
  455.                 }\
  456.                 else\
  457.                 {\
  458.                     break;\
  459.                 }\
  460.             }\
  461.             else\
  462.             {\
  463.                 if (item->_right##NameFrom)\
  464.                 {\
  465.                     item = item->_right##NameFrom;\
  466.                 }\
  467.                 else\
  468.                 {\
  469.                     break;\
  470.                 }\
  471.             }\
  472. \
  473.             bit <<= 1;\
  474.         }\
  475.     }
  476. #endif
  477.  
  478. #define BODY_UNIQUEVALUETREE_FIND(member, value, ClassFrom, NameFrom, ClassTo, NameTo) \
  479.     _BODY_VALUETREE_FIND(member, value, ClassFrom, NameFrom, ClassTo, NameTo) \
  480.     return result;
  481.  
  482. #define BODY_UNIQUEVALUETREE_FINDREVERSE(member, value, ClassFrom, NameFrom, ClassTo, NameTo) \
  483.     _BODY_VALUETREE_FIND(member, value, ClassFrom, NameFrom, ClassTo, NameTo) \
  484.     return result;
  485.  
  486. #define WRITE_UNIQUEVALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  487.     rCArchive << Get##NameTo##Count();\
  488.     { for (ClassTo* item = GetFirst##NameTo(); item; item = GetNext##NameTo(item))\
  489.           rCArchive << item->_index; }
  490.  
  491. #define READ_UNIQUEVALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  492.     {\
  493.         int count;\
  494.         int index;\
  495. \
  496.         rCArchive >> count;\
  497.         for (int i = 0; i < count; i++)\
  498.         {\
  499.             rCArchive >> index;\
  500.             Add##NameTo((ClassTo*)(pointerArray[index]));\
  501.         }\
  502.     }
  503.  
  504. #endif
  505.